<?php
/**
 * @see Alinks_Ajax_Callable_Interface
 */
require_once('Alinks/Ajax/Callable/Interface.php');

/**
 * @see Alinks_Registry
 */
require_once('Alinks/Registry.php');

/**
 * Used for getting information about the current Ajax
 * request.
 *
 * Copyright (C) 2008  Sean Hickey
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Sean Hickey <sean@headzoo.com>
 * @version $Id: Ajax.php 376 2008-07-03 05:13:37Z sean $
 * @package Alinks_Ajax
 */
class Alinks_Ajax
{
	/**
	 * Dispatches an Ajax request
	 *
	 * Looks for $_POST['method'] which will have a format like
	 * 'Alinks_Keyphrase_Keeper.fetchAll', where 'Alinks_Keyphrase_Keeper' is
	 * a class name, and 'fetchAll' is a method to call on that class.
	 *
	 * The dispatcher will look for an instance of the class in the registry,
	 * and call the method on the instance, echoing the return results.
	 */
	public static function dispatch()
	{
		if (!isset($_POST['method'])) {
			return;
		}
		
		/**
		 * Break apart the 'Alinks_Keyphrase_Keeper.fetchAll' so we can get
		 * the class name (really, the registry key), and the method name.
		 */
		$method_parts = explode('.', $_POST['method']);
		if (count($method_parts) < 2) {
			return;
		}
		
		$class = $method_parts[0];
		$method = $method_parts[1];
		if (!Alinks_Registry::exists($class)) {
			return;
		}
		
		$class = Alinks_Registry::get($class);
		if (!($class instanceof Alinks_Ajax_Callable_Interface)) {
			return;
		}
		if (!is_callable(array($class, $method))) {
			return;
		}
		
		$class->setAjaxCalling();
		$args = (isset($_POST['args'])) ? $_POST['args'] : array();

		try {
			call_user_func_array(array($class, $method), $args);
		} catch (Alinks_Exception $e) {
			self::sendResponse(false, $e->getMessage());
		}
	}
	
	/**
	 * Returns whether the current request is an Ajax request
	 *
	 * Dojo sets the X-Request-With header with the value 'XMLHttpRequest'. We
	 * know this is an Ajax request if it's set.
	 *
	 * @return bool
	 */
	public static function isAjax()
	{
		return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest');
	}
	
	/**
	 * Sends an Ajax response
	 *
	 * Sends a response to an aLinks initiated Ajax request in a way
	 * that can be understood.
	 *
	 * @param bool $success If the Ajax request was successful
	 * @param string $message Success or failure message
	 * @param array $args Additional args
	 */
	public static function sendResponse($success, $message = null, array $args = array())
	{
		$response = new stdClass();
		$response->success = $success;
		$response->message = $message;
		foreach($args as $key => $value) {
			$response->$key = $value;
		}

		echo json_encode($response);
		die();
	}
}